--[[
	Exsto
	Copyright (C) 2011  Prefanatic

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
]]

file = {}
sql = {}

function file.Read( location )
	local f = Files.GetFile( "Exsto/data/" .. location, Files.Text.Read )
	if not f then return nil end
	
	print( f:ReadString() )
	
	return f:ReadString()
end

function file.Write( location, data )
	local f = Files.GetFile( "Exsto/data/" .. location, Files.Text.Write ) or Files.CreateFile( "Exsto/data/" .. location, Files.Text.Write )
	if not f then return exsto.Print( exsto_ERROR, "Failed to write file " .. location ) end
	
	return f:WriteString( data )
end

function CurTime() return os.time() end

function sql.Query( s )
	print( s )
	if s:find( "CREATE TABLE" ) then
		s = s:gsub( "CREATE TABLE IF NOT EXISTS ", "" ) -- We should have dbName (column1, column2)
		local cstart = s:find( "(", 1, true )
		local dbName = s:sub( 1, cstart - 1 )
		local columnData = s:sub( cstart + 1, s:len() - 2 )
		
		print( dbName, columnData )
		
		Sql.CreateTable( dbName:Trim(), columnData:Trim() )
		return true
	elseif s:find( "UPDATE " ) then
		s = s:gsub( "UPDATE ", "" ) -- We should have dbName SET columnData WHERE column = data
		local sfind, sfinde = s:find( " SET " )
		local wfind, wfinde = s:find( " WHERE " )
		
		local dbName = s:sub( 1, sfind )
		local columnSet = s:sub( sfinde, wfind )
		local columnWhere = s:sub( wfinde, s:len() - 1 )
		
		return Sql.UpdateTable( dbName:Trim(), columnSet:Trim(), columnWhere:Trim() )
	elseif s:find( "INSERT INTO " ) then
		s = s:gsub( "INSERT INTO ", "" )
		local cfind = s:find( "(", 1, true )
		local vfind, vfinde = s:find( " VALUES(", 1, true )
		
		local dbName = s:sub( 1, cfind - 1 )
		local columns = s:sub( cfind + 1, vfind - 2 )
		local columnValues = s:sub( vfinde + 1, s:len() - 2 )
		
		print( columnValues )
		
		return Sql.InsertIntoTable( dbName:Trim(), columns:Trim(), columnValues:Trim() )
	elseif s:find( "DELETE FROM " ) then
		s = s:gsub( "DELETE FROM ", "" )
		local wfind, wfinde = s:find( " WHERE " )
		
		local dbName = s:sub( 1, wfind )
		local whereData = s:sub( wfinde, s:len() )
		
		return Sql.DeleteFromSQLTable( dbName:Trim(), whereData:Trim() )
		
	elseif s:find( "DROP TABLE " ) then
		s = s:gsub( "DROP TABLE ", "" )
		
		return Sql.DropTable( s:Trim() )
	elseif s:find( "SELECT " ) then
		s = s:gsub( "SELECT ", "" )
		local ffind, ffinde = s:find( " FROM " )
		
		local selectData = s:sub( 1, ffind )
		s = s:sub( ffinde, s:len() ):Trim()
		
		local dbend = s:find( " " ) or s:len()
		local dbName = s:sub( 1, dbend )
		s = s:sub( dbend, s:len() )
		
		local data = Sql.SelectFromTable( dbName, selectData, s )
		PrintTable( data )
		
		return data
	end
end
--sql.Query( "CREATE TABLE IF NOT EXISTS test_db(column1 TEXT, column2 STRING)" )
--sql.Query( "UPDATE test_db SET peanuts = 'bullshit' WHERE owner = 'muffins'" )
--sql.Query( "INSERT INTO test_db(column1, column2) VALUES('peanut', 1204)" )
--sql.Query( "DELETE FROM test_db WHERE faggot = 'grimking1'" )

function string.Left( str, len )
	return str:sub( 1, len )
end

function string.Trim(str)
	-- Function by Colandus
	return (string.gsub(str, "^%s*(.-)%s*$", "%1"))
end

function string.Explode( sep, str )
	if (sep == " ") or (not sep) then sep = "%s" end
	local tmp = {}
	for token in string.gmatch( str, "[^" .. sep .. "]+" ) do
		tmp[ #tmp + 1 ] = token
	end
	return tmp
end

function string.Implode(seperator,Table) return 
	table.concat(Table,seperator) 
end

function PrintTable( tbl, ignore, lvl )
	ignore = ignore or {}
	lvl = lvl or 0
	if (ignore[ tbl ]) then return end
	ignore[ tbl ] = true
	local str = ""
	for i=1, lvl do str = str .. "|    " end
	for key, val in pairs( tbl ) do
		if (type( val ) == "table") then
			print( str .. "[" .. tostring( key ) .. "]" )
			PrintTable( val, ignore, lvl + 1 )
			print( str )
		else
			print( str .. tostring( key ) .. " = " .. tostring( val ) )
		end
	end
end

function table.Copy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end

function table.HasValue( t, val )
	for k, v in pairs( t ) do
		if v == val then return true end
	end
	return false
end

function table.Count( t )
	local count = 0
	for k, v in pairs( t ) do
		count = count + 1
	end
	return count
end

-- Stolen from Garriehs Mode
function SQLStr( str_in, bNoQuotes )

	local str = tostring( str_in )
	
	if ( str:find( '\\"' ) ) then
		return
	end
	
	str = str:gsub( '"', '\\"' )
	
	if ( bNoQuotes ) then
		return str
	end
	
	return "\"" .. str .. "\"";

end

function tobool( a )
	if a == nil or a == false or a == 0 or a == "0" or a == "false" then return false end
	return true
end
